/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MainFrame.java
 *
 * Created on Dec 12, 2009, 10:44:07 PM
 */

package hirt;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog.ModalExclusionType;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * This class represents the upmost major overarching GUI element to the hirt
 * client. Conceptually, all user interface communication between the core client
 * code should go through this class by wrappers and handling funcitons.
 * @author puzzud
 */
public class MainFrame extends JFrame
{
    /**
     * Main GUI component for the client.
     */
    MainScreenPanel mainScreenPanel;

    /**
     * JPanel that contains the GameScenePanel.
     */
    JPanel ScenePanel;

    /**
     * JPanel that contains the real time graphics for the scene.
     */
    GameScenePanel gameScenePanel;

    /**
     * Reference to the main client.
     */
    HirtClient client;

    /**
     * An Item reference to which Item2D has been left clicked by the mouse.
     */
    Item mouseLeftClickedItemReference;

    /**
     * An Item reference to which Item2D has been middle clicked by the mouse.
     */
    Item mouseMiddleClickedItemReference;

    /**
     * An Item reference to which Item2D has been right clicked by the mouse.
     */
    Item mouseRightClickedItemReference;

    /**
     * An Item reference to which Item2D is being hovered or mouse overed.
     * NOT USED.
     */
    Item mouseOverItemReference;

    /**
     * An Item reference to which Item2D is currently being dragged by the mouse.
     */
    Item mouseDraggedItemReference;

    /**
     * Default constructor for MainFrame. Creates the three major components of
     * a hirt client:  the client itself, the MainScreenPanel, and the GameScenePanel.
     */
    public MainFrame()
    {
        this.setTitle( "HIRT" );
        //setLocationRelativeTo( null );

        // Initialize client and references to other key _core_ objects.
        client = new HirtClient( this );

        // Initialize major GUI objects.
        mainScreenPanel = new MainScreenPanel( client );
        gameScenePanel = new GameScenePanel( client );

        // GUI manipulating code that (for now) brings up main 'game' scene panel (instead of login/lobby).
        Container content = getContentPane();
        content.add( mainScreenPanel );
        pack();

        initComponents();

        setSize( mainScreenPanel.getPreferredSize().width, mainScreenPanel.getPreferredSize().height );
        setPreferredSize( new Dimension(mainScreenPanel.getPreferredSize().width, mainScreenPanel.getPreferredSize().height ) );
        //setVisible( true );

        // For now, must be added after the main frame is visible, in order to operate correctly.
        ScenePanel = mainScreenPanel.frmScene;
        ScenePanel.add( gameScenePanel );
        ScenePanel.setFocusable( true );
        pack();

        if( !client.getDebugMode() )
        {
            setVisible( false );
            LoginFrame loginFrame = new LoginFrame( client );
            loginFrame.setLocationRelativeTo( null );

            loginFrame.setVisible( true );
            loginFrame.setModalExclusionType( ModalExclusionType.APPLICATION_EXCLUDE );
        }
        else
        {
            setVisible( true );
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setMinimumSize(new java.awt.Dimension(1024, 768));
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                formComponentResized(evt);
            }
        });
        addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                formMouseDragged(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 782, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 549, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * When the overarching JFrame is resized, the inner MainScreenPanel and
     * GameScenePanel is resized manually.
     * @param evt ComponentEvent
     */
    private void formComponentResized(java.awt.event.ComponentEvent evt)//GEN-FIRST:event_formComponentResized
    {//GEN-HEADEREND:event_formComponentResized
        Component c = evt.getComponent();

        mainScreenPanel.setSize( c.getWidth(), c.getHeight() );
        gameScenePanel.drawBackground( true );

        //System.out.println( "Help, I'm being resized!!!!!!!!!");
    }//GEN-LAST:event_formComponentResized

    /**
     * UNUSED.
     * @param evt
     */
    private void formMouseDragged(java.awt.event.MouseEvent evt)//GEN-FIRST:event_formMouseDragged
    {//GEN-HEADEREND:event_formMouseDragged
        // TODO add your handling code here:
        //System.out.println( "Dragon!" );
    }//GEN-LAST:event_formMouseDragged


    /**
    * Main function to run this client alone without a server.
    * @param args the command line arguments
    */
    public static void main(String args[])
    {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MainFrame();//.setVisible(true);
            }
        });
    }

    /**
     * Handle incoming chat messages.
     * @param message Literal chat message String.
     */
    public void recieveChat(String message)
    {
        mainScreenPanel.WriteChatMessage(message);
    }

    /**
     * Handle incoming request messages, such as requesting another Item to move.
     * @param message String representation of a request.
     */
    public void recieveRequest(String message)
    {
        mainScreenPanel.WriteRequestMessage(message);
    }

    /**
     * Handle incoming item movements, such as items moving coordinates and angle.
     * @param movementAction action object with movement detail.
     */
    public void receiveItemMove( MovementAction movementAction )
    {
        gameScenePanel.receiveItemMove( movementAction );
    }

    /**
     * Handle incoming item transfer, such as taking an item and putting it inside
     * another item.
     * @param transferAction action object with transfer detail.
     */
    public void receiveItemTransfer( TransferAction transferAction )
    {
        //System.out.println( "MainFrame.receiveItemTransfer()................" );

        // TODO: Move this code to hirtClient before this function is called.
        //Item actor = transferAction.getActor();
        Item transferredItem = transferAction.moved;
        Item reciever = transferAction.reciever;
        Item container = transferredItem.container;

        Scenario currentScenario = client.getSession().getCurrentScenario();

        if( currentScenario == null )
        {
            return;
        }

        if( container != null )
        {
            container.removeItem( transferredItem );
            reciever.putItem( transferredItem );
        }
        
        // END Move code.
        gameScenePanel.receiveItemTransfer( transferAction );

        mainScreenPanel.refreshItems();
    }

    /**
     * Handle incoming item creation message, such as when the server is informing
     * the client that a new object is to be observed and added locatlly.
     * @param creationAction action object with creation details.
     */
    public void receiveItemCreation( CreationAction creationAction )
    {
        // TODO: Move this code to hirtClient before this function is called.
        Item createdItem = creationAction.actor;
        //Scenario currentScenario = client.getSession().getCurrentScenario();

        if( creationAction.firstTime && creationAction.type == CreationAction.PLAYER )
        {
            Player newPlayer = ( Player )createdItem;
            recieveChat( newPlayer.name + " Just joined the game" );
            mainScreenPanel.refreshResponders();
        }
        else if( createdItem.getType().equals( "world" ) )
        {
            client.getSession().getCurrentScenario().setWorld( ( Item2D )createdItem);
        }

        gameScenePanel.receiveItemCreation( creationAction );
    }

    /**
     * Not quite sure honestly. Not quite sure if it is even used.
     * @param enable state of whether to enable this or not.
     */
    public void enableGameStart(boolean enable)
    {
        mainScreenPanel.btnCreateScenario.enableInputMethods(enable);
    }

    /**
     * Handle incoming name change for any player (including local player).
     * @param action PlayerChangeAction
     */
    void recieveNameChange(PlayerChangeAction action)
    {
        Player player = (Player)action.actor;
        recieveChat(player.getName() + " changed his name to " + action.newName);
        player.setName(action.newName);
    }

    /**
     * Handle an addition role change from the client.
     * @param newRole new role class object that has been added to the local player.
     */
    void recieveAddRole(Role newRole)
    {
    //    throw new UnsupportedOperationException("Not yet implemented");
    }

    /**
     * Handle a removal of role change from the client.
     * @param newRole new role class object that has been removed from the local player.
     */
    void recieveRemoveRole(Role newRole)
    {
    //    throw new UnsupportedOperationException("Not yet implemented");
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
}

